function getUID(length) {
    if (!length) length = 5;
    return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36);
}

// 获取本地化语言
function api_locales(message, placeholders) {
    var res = chrome.i18n.getMessage(message, placeholders);
    return res ? res : message;
}

function api_runtime_on_message_listener(callback) {
    chrome.runtime.onMessage.addListener(callback);
}

var messageAsyncCallbackRegister = {};
function api_send_message(message, callback) {
    message['UID'] = getUID();
    if (message.hasOwnProperty('callback')) {
        messageAsyncCallbackRegister[message['UID']] = message.callback;
    }
    chrome.runtime.sendMessage(message, callback)
}
function api_send_callback_message(sender, fromMessage, returnMessage) {
    if (typeof returnMessage != 'object') api_send_callback_message = {};
    returnMessage['from'] = fromMessage['type'];
    returnMessage['type'] = 'messageCallback';
    returnMessage['UID'] = fromMessage['UID'];
    api_send_tab_message(sender.tab.id, returnMessage)
}
function api_message_callback(message) {
    if (messageAsyncCallbackRegister.hasOwnProperty(message['UID'])) {
        messageAsyncCallbackRegister[message['UID']] && messageAsyncCallbackRegister[message['UID']](message);
        delete messageAsyncCallbackRegister[message['UID']];
    }
}

function api_send_tab_message(tabID, message, callback) {
    chrome.tabs.sendMessage(tabID, message, callback)
}

function api_tab_captureVisibleTab(callback) {
    chrome.tabs.captureVisibleTab(callback)
}

function api_storage_sync_set(data, callback) {
    chrome.storage.sync.set(data, callback)
}

function api_storage_sync_get(data, callback) {
    chrome.storage.sync.get(data, callback)
}

function api_storage_sync_remove(data, callback) {
    chrome.storage.sync.remove(data, callback)
}

function api_storage_local_remove(data, callback) {
    chrome.storage.local.remove(data, callback)
}

function api_storage_local_set(data, callback) {
    chrome.storage.local.set(data, callback)
}

function api_storage_local_get(data, callback) {
    chrome.storage.local.get(data, callback)
}

function api_storage_local_remove(data, callback) {
    chrome.storage.local.get(data, callback)
}

function api_storage_on_change_listener(callback) {
    chrome.storage.onChanged.addListener(callback)
}

function api_bookmark_get(idOrIdList, callback) {
    chrome.bookmarks.get(idOrIdList, callback);
}

function api_bookmark_query(query, callback) {
    chrome.bookmarks.search(query, callback);
}

function api_bookmark_getRecent(numberOfItems, callback) {
    chrome.bookmarks.getRecent(numberOfItems, callback);
}

function api_bookmark_getChildren(stringID, callback) {
    chrome.bookmarks.getChildren(stringID, callback);
}

function api_history_query(query, callback) {
    chrome.history.search(query, callback);
}

function api_notifications_create(options, callback) {
    chrome.notifications.create(options, callback);
}

function eval_inject_code(code) {
    return code
}

function api_execute_script(tabId, details, callback) {
    chrome.scripting.executeScript({
        target: {tabId: tabId},
        func: eval_inject_code,
        args: [details.code]
    }, callback);
}

function api_manifest() {
    return chrome.runtime.getManifest()
}

function api_enterprise_networkDetails(callback) {
    chrome.enterprise.networkingAttributes.getNetworkDetails(callback)
}

function api_sessions_getDevices(filter, callback) {
    chrome.sessions.getDevices(filter, callback)
}

function api_sessions_getRecentlyClosed(filter, callback) {
    chrome.sessions.getRecentlyClosed(filter, callback)
}

function api_sessions_restore(sessionId, callback) {
    chrome.sessions.restore(sessionId !== null ? sessionId + '' : sessionId, callback)
}

function api_get_available_static_rule_count(callback) {
    return chrome.declarativeNetRequest.getAvailableStaticRuleCount(callback)
}

function api_get_dynamic_rules(callback) {
    return chrome.declarativeNetRequest.getDynamicRules(callback)
}

function api_get_enabled_rulesets(callback) {
    return chrome.declarativeNetRequest.getEnabledRulesets(callback)
}

function api_get_matched_rules(filter, callback) {
    return chrome.declarativeNetRequest.getMatchedRules(filter, callback)
}

function api_get_session_rules(callback) {
    return chrome.declarativeNetRequest.getSessionRules(callback)
}

function api_is_regex_supported(regexOptions, callback) {
    return chrome.declarativeNetRequest.isRegexSupported(regexOptions, callback)
}

function api_set_extension_action_options(options, callback) {
    return chrome.declarativeNetRequest.setExtensionActionOptions(options, callback)
}

function api_test_match_outcome(request, callback) {
    return chrome.declarativeNetRequest.testMatchOutcome(request, callback)
}

function api_update_dynamic_rules(options, callback) {
    return chrome.declarativeNetRequest.updateDynamicRules(options, callback)
}

function api_update_enabled_rulesets(options, callback) {
    return chrome.declarativeNetRequest.updateEnabledRulesets(options, callback)
}

function api_update_session_rules(options, callback) {
    return chrome.declarativeNetRequest.updateSessionRules(options, callback)
}

function api_cookie_get(details, callback) {
    return chrome.cookies.get(details, callback);
}

function api_cookie_getAll(details, callback) {
    return chrome.cookies.getAll(details, callback);
}

function api_cookie_getAllCookieStores(callback) {
    return chrome.cookies.getAllCookieStores(callback);
}

function api_cookie_remove(details, callback) {
    return chrome.cookies.remove(details, callback);
}

function api_cookie_set(details, callback) {
    return chrome.cookies.set(details, callback);
}
function api_getURL(url) {
    return chrome.runtime.getURL(url)
}

function api_getIcon(url, size) {
    if (!size) size = 16;
    
    return "_favicon/?page_url="+url+"&size=" + size;
}

function api_locale_language() {
    return chrome.i18n.getUILanguage();
}


function api_tab_onupdated(callback) {
    chrome.tabs.onUpdated.addListener(callback);
}

function api_tab_goForward(tabId, callback) {
    chrome.tabs.goForward(tabId, callback);
}

function api_tab_goBack(tabId, callback) {
    chrome.tabs.goBack(tabId, callback);
}

function api_tab_copy(tabId, callback) {
    if (tabId) {
        chrome.tabs.duplicate(tabId, callback);
    } else {
        api_tab_current(function (tab) {
            chrome.tabs.duplicate(tab[0].id, callback);
        });
    }
}

function api_tab_create(url, callback) {
    let config = typeof url == 'object' ? url : { url: url };
    chrome.tabs.create(config, callback);
}

function api_tab_get(tabId, callback) {
    chrome.tabs.get(tabId, callback);
}

function api_tab_update(tabId, data, callback) {
    chrome.tabs.update(tabId, data, callback)
}

function api_tab_current(callback) {
    api_tab_query({ active: true, currentWindow: true }, callback);
}

function api_tab_query(query, callback) {
    chrome.tabs.query(query, callback);
}

function api_tab_remove(tabIds, callback) {
    chrome.tabs.remove(tabIds, callback)
}

function api_window_create(createData, callback) {
    chrome.windows.create(createData, callback)
}

function api_window_current(data, callback) {
    chrome.windows.getCurrent(data, callback)
}

function api_window_update(windowId, updateInfo, callback) {
    chrome.windows.update(windowId, updateInfo, callback)
}
